package com.tianlh.service.impl.redis.ReentrantLock;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import redis.clients.jedis.Jedis;

/**
 * @Desc 两个线程交替顺序打印1-100之间的数，一个打印奇数一个打印偶数
 * @author 黑子
 * @Date 2018/1/11 17:40
 */
public class Test {

    public static void main(String[] args) throws InterruptedException, IOException {
        List<Thread> threads = createThreads(5);
        //开始任务
        for (Thread t : threads) {
            t.start();
        }
        // 执行60秒
        Thread.sleep(60 * 1000);
        //停止所有线程
        Task.alive = false;
        // 等待所有线程终止
        for (Thread t : threads) {
            t.join();
        }
    }


    private static List<Thread> createThreads(int count) throws IOException {
        List<Thread> threads = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            Jedis jedis = new Jedis("localhost", 6379);
            RedisReentrantLock lock = new RedisReentrantLock(jedis);
            Task task = new Task(lock);
            Thread t = new Thread(task);
            threads.add(t);
        }
        return threads;
    }

    private static class Task implements Runnable {

        private RedisReentrantLock lock;

        private final int MAX_ENTRANT = 5;

        private final Random random = new Random();

        private static boolean alive = true;

        Task(RedisReentrantLock lock) {
            this.lock = lock;
        }

        @Override
        public void run() {
            while (alive) {
                int times = random.nextInt(MAX_ENTRANT);
                doLock(times);
            }
        }

        private void doLock(int times) {
            try{
                if (lock.tryLock(5, TimeUnit.SECONDS)) {
                    try {
                        if (times > 0) {
                            doLock(--times);
                        }
                    } finally {
                        if (lock != null) {
                            lock.unlock();
                        }
                    }
                }
            }catch (Exception e){

            }
        }
    }
}
